package com.hxk.juc.thread.CCS;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * CountDownLatch和CyclicBarrier都不能重复使用
 *      CyclicBarrier：+加到设定值，放开阻塞执行某个线程
 *      CountDownLatch：-減到0时，放开阻塞执行某些线程
 *  而在我们实际的业务场景中会遇到，比如停车场有100个车位，但是有150个汽车去抢这100个车位的现象，
 *      那么就会有100个车主抢到车位，而50个车主抢不到车位的现象，而这50个车主不是走掉，而是等着，
 *      等已经停好的100个车子停车时间到后，走一个他们在进去一个业务场景
 *  遇到这种业务场景，显而CountDownLatch和CyclicBarrier是无法实现的，这时我们就可以使用juc提出的Semaphore就可以实现
 *  本case就是模拟停车场有5个车位，然后来了10辆车要去争抢5个车位的过程
 */
public class SemaphoreCase {
    public static void main(String[] args) {
        //这里的5就是指停车场的5个车位
        Semaphore semaphore = new Semaphore(5);

        //来了10两汽车
        for (int i = 1; i <= 10; i++) {
            final int temp = i;
            new Thread(()->{
                try {
                    //这里我抢到了，在我的停车时间没有到时，我占着这个车位
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"\t 抢到了车位");
                    try {
                        //在停车场停车的时间
                        TimeUnit.SECONDS.sleep(temp);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"\t 停车"+temp+"秒，离开停车场");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    //停车的时间到了，离开停车场
                    semaphore.release();
                }
            },i+"号汽车").start();
        }
    }
}
